#include "layerstyledialog.h"
#include "ui_layerstyledialog.h"

#include "util/logger.h"
#include "util/utility.h"
#include "util/appevent.h"

#include "Widget/colorblockwidget.h"
#include "Geo/utility/filereader.h"

#include "Geo/map/geofeature.h"
#include "Geo/map/geolayer.h"
#include "Geo/geo_base.h"
#include <QFrame>
#include <QHBoxLayout>
#include <QTableWidget>
#include <QString>
#include <QVBoxLayout>
#include <QStringList>
#include <QFormLayout>
#include <QTabWidget>
#include <QCheckBox>
#include <QFileDialog>
#include <QFormLayout>
#include <QIcon>
#include <QLabel>
#include <QLinearGradient>
#include <QMessageBox>
#include <QPainter>
#include <QPalette>
#include <QPixmap>
#include <QSpacerItem>
#include <QString>
#include <QStringList>
#include <QStyledItemDelegate>

LayerStyleDialog::LayerStyleDialog(GeoFeatureLayer* layerIn,QWidget *parent) :
    QDialog(parent),layer(layerIn),
    ui(new Ui::LayerStyleDialog)
{
    ui->setupUi(this);

    this->setWindowTitle(tr("LayerStyles"));
    this->setAttribute(Qt::WA_DeleteOnClose, true);
    // color pairs
    colorPairs.reserve(4);
    colorPairs.emplace_back(QColor(230, 190, 255), QColor(255, 0, 255));
    colorPairs.emplace_back(QColor(200, 0, 0), QColor(125, 25, 25));
    colorPairs.emplace_back(QColor(170, 255, 170), QColor(0, 255, 0));
    colorPairs.emplace_back(QColor(0, 255, 0), QColor(255, 0, 0));

    setupLayout();

    connect(this, &LayerStyleDialog::sigUpdateOpengl,
            AppEvent::getInstance(), &AppEvent::onUpdateOpengl);
    connect(this,&LayerStyleDialog::sigAddColorTreeBlock,
            AppEvent::getInstance(),&AppEvent::on_AddColorTreeBlock);

    setFeatureLayer(layer);
}

LayerStyleDialog::~LayerStyleDialog()
{
    delete ui;
}

// Layout
void LayerStyleDialog::setupLayout()
{
    layoutMainDialog=new QHBoxLayout(this);
    tabLayelStyle=new QTabWidget(this);
    pageGeomInfo=new QWidget(this);
    pageLayerStyle=new QWidget(this);
    layoutPageGeomInfo=new QVBoxLayout(pageGeomInfo);
    layoutPageLayerStyle=new QVBoxLayout(pageLayerStyle);
    tabLayelStyle->addTab(pageGeomInfo,tr("Geom Info"));
    tabLayelStyle->addTab(pageLayerStyle,tr("Layer Style"));
    layoutMainDialog->addWidget(tabLayelStyle);
    setLayoutTab1();
    setLayoutTab2();
}

void LayerStyleDialog::setLayoutTab1()
{
    QFormLayout *formLayout = new QFormLayout();
    /* Brief Information */
    labelFID = new QLabel(this);
    QFrame* frame = new QFrame(this);
    frame->setFrameStyle(QFrame::Panel | QFrame::Raised);
    labelExtentMinX = new QLabel(frame);
    labelExtentMaxX = new QLabel(frame);
    labelExtentMinY = new QLabel(frame);
    labelExtentMaxY = new QLabel(frame);
    labelGeomType = new QLabel(frame);
    labelLayerName = new QLabel(frame);
    QVBoxLayout* extentLayout = new QVBoxLayout(frame);
    QHBoxLayout* extentRow1Layout = new QHBoxLayout();
    QHBoxLayout* extentRow2Layout = new QHBoxLayout();
    QHBoxLayout* extentRow3Layout = new QHBoxLayout();
    extentRow1Layout->addStretch();
    extentRow1Layout->addWidget(labelExtentMaxY);
    extentRow1Layout->addStretch();
    extentRow2Layout->addWidget(labelExtentMinX);
    extentRow2Layout->addStretch();
    extentRow2Layout->addWidget(labelExtentMaxX);
    extentRow3Layout->addStretch();
    extentRow3Layout->addWidget(labelExtentMinY);
    extentRow3Layout->addStretch();
    extentLayout->addLayout(extentRow1Layout);
    extentLayout->addLayout(extentRow2Layout);
    extentLayout->addLayout(extentRow3Layout);

    formLayout->addRow(new QLabel("Layer Name:", this), labelLayerName);
    formLayout->addRow(new QLabel("Geommetry Type:", this), labelGeomType);
    formLayout->addRow(new QLabel("Extent:", this), frame);

    // Detailed information [Attribute records]
    attributeTableLayout = new QHBoxLayout();
    attributeTable = new QTableWidget(this);
    attributeTable->setEditTriggers(QTableWidget::NoEditTriggers);
    attributeTableLayout->addWidget(attributeTable);
    attributeTableLayout->setEnabled(true);

    // Show more
    btnShowMore = new QPushButton(this);
    btnShowMore->setIcon(QIcon("../Resources/icons/show-more.ico"));
    connect(btnShowMore, &QPushButton::clicked, this, [this] {
        if (this->attributeTable->isHidden()) {
            this->attributeTable->setHidden(false);
            this->btnShowMore->setIcon(QIcon("../Resources/icons/show-less.ico"));
            this->setFixedHeight(500);
        }
        else {
            this->attributeTable->setHidden(true);
            this->btnShowMore->setIcon(QIcon("../Resources/icons/show-more.ico"));
            this->setFixedHeight(0);
        }
    });
    layoutPageGeomInfo->addLayout(formLayout);
    layoutPageGeomInfo->addWidget(btnShowMore);
    layoutPageGeomInfo->addLayout(attributeTableLayout);
}

void LayerStyleDialog::setLayoutTab2()
{
    modeComboBox = new QComboBox(this);
    QStyledItemDelegate* delegate = new QStyledItemDelegate(this);
    modeComboBox->setItemDelegate(delegate);
    QStringList modeList;
    modeList << "Single symbol" << "Categorized" ;
    modeComboBox->setEditable(false);
    modeComboBox->addItems(modeList);
    // create pages for differnt style-type
    createPageSingleStyle();
    createPageCategorizedStyle();
    stackedLayout = new QStackedLayout();
    stackedLayout->addWidget(singleStyleWidget);
    stackedLayout->addWidget(categorizedStyleWidget);

    QHBoxLayout* btnLayout = new QHBoxLayout();
    //btnLoadSLD = new QPushButton(tr("Load Style"), this);
    btnOk = new QPushButton(tr("OK"), this);
    btnCancel = new QPushButton(tr("Cancel"), this);
    btnApply = new QPushButton(tr("Apply"), this);
    btnLayout->addWidget(btnOk);
    btnLayout->addWidget(btnCancel);
    btnLayout->addWidget(btnApply);
    // respond to the enter key
    btnOk->setFocus();
    btnOk->setDefault(true);


    connect(modeComboBox, SIGNAL(currentIndexChanged(int)),
        stackedLayout, SLOT(setCurrentIndex(int)));
    //connect(btnLoadSLD, &QPushButton::clicked,
        //this, &LayerStyleDialog::onBtnLoadSldClicked);
    connect(btnOk, &QPushButton::clicked,
        this, &LayerStyleDialog::onBtnOkClicked);
    connect(btnApply, &QPushButton::clicked,
        this, &LayerStyleDialog::onBtnApplyClicked);
    connect(btnCancel, &QPushButton::clicked,
        this, &LayerStyleDialog::close);

    modeComboBox->setCurrentIndex(layer->getStyleMode());
    layoutPageLayerStyle->addWidget(modeComboBox);
    layoutPageLayerStyle->addLayout(stackedLayout);
    layoutPageLayerStyle->addLayout(btnLayout);
}

void LayerStyleDialog::setFeatureLayer(GeoFeatureLayer* layer)
{
    GeoExtent extent = layer->getExtent();
    GeoFeature* feature = layer->getFeatureByFID(1);
    labelGeomType->setText(feature->getGeometry()->getGeometryName());
    //GeometryType curGeometryType=layer->
    labelExtentMinX->setText(QString::number(extent.minX));
    labelExtentMaxX->setText(QString::number(extent.maxX));
    labelExtentMinY->setText(QString::number(extent.minY));
    labelExtentMaxY->setText(QString::number(extent.maxY));
    labelLayerName->setText(layer->getName());

    readProTable(layer);
}

void LayerStyleDialog::readProTable(GeoFeatureLayer* layer)
{
    if (!layer || layer->isEmpty())
    {
        return;
    }
    int featuresCount = layer->getFeatureCount();
    int fieldsCount = layer->getNumFields();

    attributeTable->clear();
    //attributeTable->setAlternatingRowColors(true);
    attributeTable->setColumnCount(fieldsCount + 1);
    attributeTable->setRowCount(featuresCount + 1);
    attributeTable->setEditTriggers(QAbstractItemView::NoEditTriggers);
    attributeTable->horizontalHeader()->setStyleSheet(
        "QHeaderView::section{background::rgb(0,122,204);}"
    );
    QStringList header;
    header << "FID";
    for (int i = 0; i < fieldsCount; ++i)
    {
        header << layer->getFieldDefn(i)->getName();
    }
    attributeTable->setHorizontalHeaderLabels(header);

    for (int iFeature = 0; iFeature < featuresCount; ++iFeature)
    {
        GeoFeature *feature = layer->getFeature(iFeature);
        if (!feature || feature->isDeleted())
        {
            continue;
        }

        QTableWidgetItem* item = new QTableWidgetItem();
        item->setTextAlignment(Qt::AlignRight);
        item->setText(QString::number(feature->getFID()));
        attributeTable->setItem(iFeature, 0, item);
        for (int iCol = 0; iCol < fieldsCount; ++iCol) {
            QTableWidgetItem* item = new QTableWidgetItem();
            GeoFieldDefn* fieldDefn = layer->getFieldDefn(iCol);
            switch (fieldDefn->getType()){
            default:
                break;
            case kFieldInt:{
                item->setTextAlignment(Qt::AlignRight);
                int value;
                feature->getField(iCol, &value);
                item->setText(QString::number(value));
                break;
            }
            case kFieldDouble:{
                item->setTextAlignment(Qt::AlignRight);
                double value;
                feature->getField(iCol, &value);
                item->setText(QString::number(value));
                break;
            }
            case kFieldText:{
                item->setTextAlignment(Qt::AlignLeft);
                QString value;
                feature->getField(iCol, &value);
                item->setText(value);
                break;
            }
            }// end switch
            attributeTable->setItem(iFeature, iCol + 1, item);

        }// end for iCol
    }
}
// Single style
void LayerStyleDialog::createPageSingleStyle()
{
    singleStyleWidget = new QWidget(this);
    QHBoxLayout* layout = new QHBoxLayout(singleStyleWidget);
    colorSelectWidget = new QColorDialog(this);
    colorSelectWidget->setWindowFlag(Qt::Widget);
    colorSelectWidget->setOptions(QColorDialog::DontUseNativeDialog | QColorDialog::NoButtons);
    layout->addWidget(colorSelectWidget);
}

// Classify style
void LayerStyleDialog::createPageCategorizedStyle()
{
    categorizedStyleWidget = new QWidget(this);
    QVBoxLayout* layout = new QVBoxLayout(categorizedStyleWidget);
    QFormLayout* formLayout = new QFormLayout();
    //formLayout->setLabelAlignment(Qt::AlignRight);

    QLabel* label1 = new QLabel(tr("Field"), categorizedStyleWidget);
    classifyFieldComboBox = new QComboBox(categorizedStyleWidget);
    classifyFieldComboBox->setEditable(false);
    classifyFieldComboBox->addItems(layer->getFieldList());
    formLayout->addRow(label1, classifyFieldComboBox);

    QLabel* label2 = new QLabel(tr("Color ramp"), categorizedStyleWidget);
    colorRampComboBox = new QComboBox(categorizedStyleWidget);
    createColorRampItems();
    colorRampComboBox->setEditable(false);
    QStyledItemDelegate* delegate = new QStyledItemDelegate(this);
    colorRampComboBox->setItemDelegate(delegate);
    formLayout->addRow(label2, colorRampComboBox);
    //===========
    QFormLayout *formLayout2=new QFormLayout();
    QFormLayout *formLayout3=new QFormLayout();
    QHBoxLayout *layoutKindSetting=new QHBoxLayout();
    classifyMethodComboBox=new QComboBox();
    classifyMethodComboBox->addItem(QObject::tr("Mean"));
    classifyMethodComboBox->addItem(QObject::tr("Custom"));
    QLabel *labelMethod=new QLabel(QObject::tr("Classify Method:"));
    QLabel *labelKindNum=new QLabel(QObject::tr("Kind Num"));
    spinboxKindNum=new QSpinBox();
    spinboxKindNum->setValue(5);
    formLayout2->insertRow(0,labelMethod,classifyMethodComboBox);
    formLayout3->insertRow(0,labelKindNum,spinboxKindNum);
    layoutKindSetting->addLayout(formLayout2);
    layoutKindSetting->addLayout(formLayout3);
    //===========
    classifyResultWidget = new QTableWidget(categorizedStyleWidget);
    classifyResultWidget->setShowGrid(false);
    //classifyResultWidget->horizontalHeader()->setFixedHeight(20);
    classifyResultWidget->horizontalHeader()->setStretchLastSection(true);
    classifyResultWidget->setSelectionMode(QAbstractItemView::SingleSelection);
    classifyResultWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
    //classifyResultWidget->horizontalHeader()->setStyleSheet("QHeaderView::section{background:rgb(0,122,204);}");
    classifyResultWidget->setColumnCount(3);
    QStringList header;
    header << "Symbol" << "Value" << "legend";
    classifyResultWidget->setHorizontalHeaderLabels(header);
    classifyResultWidget->setColumnWidth(0, 50);
    classifyResultWidget->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Fixed);

    interruptWidget=new QTableWidget();
    interruptWidget->setColumnCount(1);
    QStringList header2;
    header2 << "Interrupt" ;
    interruptWidget->setHorizontalHeaderLabels(header2);
    QSplitter *splitter=new QSplitter(Qt::Horizontal,this);
    //QSplitter *splitter2=new QSplitter(Qt::Vertical,this);

    //splitter->addWidget(new QListView());
    splitter->addWidget(classifyResultWidget);
    splitter->addWidget(interruptWidget);
    splitter->setStretchFactor(0,4);
    splitter->setStretchFactor(1,1);
    layout->addLayout(formLayout);
    layout->addLayout(layoutKindSetting);
    layout->addWidget(splitter);

    QHBoxLayout* hLayout = new QHBoxLayout();
    btnClassify = new QPushButton(tr("Classify"), categorizedStyleWidget);
    connect(btnClassify, &QPushButton::clicked, this, &LayerStyleDialog::onClassify);
    hLayout->addWidget(btnClassify);
    layout->addLayout(hLayout);
}


// create color ramp bar
void LayerStyleDialog::createColorRampItems()
{
    // random color
    addRandomColorRamp();

    // color ramp
    int colorPairsCount = colorPairs.size();
    for (int i = 0; i < colorPairsCount; ++i)
    {
        addColorRamp(colorPairs[i].first, colorPairs[i].second);
    }
}

void LayerStyleDialog::addColorRamp(const QColor& startColor, const QColor& endColor)
{
    int itemWidth = 470;
    int itemHeight = 20;

    QPixmap colorRamp(itemWidth, itemHeight);
    colorRamp.fill(QColor(Qt::white));
    QPainter p(&colorRamp);
    p.setRenderHint(QPainter::Antialiasing, true);
    QLinearGradient grad(0, itemHeight / 2, itemWidth, itemHeight / 2);
    grad.setColorAt(0.0, startColor);
    grad.setColorAt(1.0, endColor);
    p.fillRect(QRect(0, 0, itemWidth, itemHeight), grad);

    QIcon icon;
    icon.addPixmap(colorRamp, QIcon::Normal, QIcon::On);

    colorRampComboBox->addItem(icon, nullptr);
    colorRampComboBox->setIconSize(QSize(itemWidth, itemHeight));
}

void LayerStyleDialog::addRandomColorRamp()
{
    int itemWidth = 470;
    int itemHeight = 20;

    QPixmap colorRamp(itemWidth, itemHeight);
    colorRamp.fill(QColor(Qt::white));
    QPainter p(&colorRamp);
    p.setRenderHint(QPainter::Antialiasing, true);
    QLinearGradient grad(0, itemHeight / 2, itemWidth, itemHeight / 2);
    for (double i = 0.0; i < 1.0; i += 0.02) {
        grad.setColorAt(i, QColor(rand() % 256, rand() % 256, rand() % 256));
    }
    p.fillRect(QRect(0, 0, itemWidth, itemHeight), grad);

    QIcon icon;
    icon.addPixmap(colorRamp, QIcon::Normal, QIcon::On);

    colorRampComboBox->addItem(icon, nullptr);
    colorRampComboBox->setIconSize(QSize(itemWidth, itemHeight));
}



/**************************************/
/*                                    */
/*            Slots                   */
/*                                    */
/**************************************/

// Button: OK
//  = Apply + Close
void LayerStyleDialog::onBtnOkClicked()
{
    onBtnApplyClicked();
    this->close();
}


// Button: Apply
void LayerStyleDialog::onBtnApplyClicked()
{
    int modeIndex = modeComboBox->currentIndex();
    switch (modeIndex)
    {
    default:
        break;
    case 0:
        processSingleStyle();
        break;
    case 1:
        processCategorizedStyle2();
        break;
    case 2:
        //processRuleBasedStyle();
        break;
    }

    layer->setStyleMode(LayerStyleMode(modeIndex));
}

// Do classify
void LayerStyleDialog::onClassify()
{
    int featuresCount = layer->getFeatureCount();
    classifyResultWidget->clearContents();
    classifyResultWidget->setRowCount(featuresCount);

    int fieldIndex = classifyFieldComboBox->currentIndex();
    GeoFieldDefn* fieldDefn = layer->getFieldDefn(fieldIndex);

    int colorRampIndex = colorRampComboBox->currentIndex();

    switch (fieldDefn->getType())
    {
    default:
        break;
    case kFieldInt:

        if (colorRampIndex == 0)
            classifyRandomColor<int>(fieldIndex);
        else
            classifyInt(fieldIndex,colorPairs[colorRampIndex - 1].first, colorPairs[colorRampIndex - 1].second);
            //classify<int>(fieldIndex,colorPairs[colorRampIndex - 1].first, colorPairs[colorRampIndex - 1].second);
        break;
    case kFieldDouble:
        if (colorRampIndex == 0)
            classifyRandomColor<double>(fieldIndex);
        else
            classifyDouble(fieldIndex,colorPairs[colorRampIndex - 1].first, colorPairs[colorRampIndex - 1].second);
            //classify<double>(fieldIndex,colorPairs[colorRampIndex - 1].first, colorPairs[colorRampIndex - 1].second);
        break;
    case kFieldText:
        if (colorRampIndex == 0)
            classifyRandomColor<QString>(fieldIndex);
        else
            classifyString(fieldIndex,colorPairs[colorRampIndex - 1].first, colorPairs[colorRampIndex - 1].second);
            //classify<QString>(fieldIndex,colorPairs[colorRampIndex - 1].first, colorPairs[colorRampIndex - 1].second);
        break;
    }
}

QVector<QString> LayerStyleDialog::getFieldKinds(int fieldIndex)
{
    QVector<QString> result;
    int featureCount=layer->getFeatureCount();
    //int fieldCount=layer->getNumFields();
    for(int iFeature=0;iFeature<featureCount;++iFeature)
    {
        GeoFeature *feature=layer->getFeature(iFeature);
        GeoFieldDefn *fieldDefn=layer->getFieldDefn(fieldIndex);
        GeoFieldType fieldType=fieldDefn->getType();
        switch(fieldType)
        {
        default:
            break;
        case kFieldInt:{
            int value;
            feature->getField(fieldIndex,&value);
            QString value_str=QString::number(value);
            if(!result.contains(value_str))
            {
                result.append(value_str);
            }
            break;
        }
        case kFieldDouble:{
            double value;
            feature->getField(fieldIndex,&value);
            QString value_str=QString::number(value);
            if(!result.contains(value_str))
            {
                result.append(value_str);
            }
            break;
        }
        case kFieldText:{
            QString value;
            feature->getField(fieldIndex,&value);
            QString value_str=value;
            if(!result.contains(value_str))
            {
                result.append(value_str);
            }
            break;
        }
        }//end switch
    }//end for all features
    return result;
}
// 1. single style
void LayerStyleDialog::processSingleStyle()
{
    QColor color = colorSelectWidget->currentColor();

    int featuresCount = layer->getFeatureCount();

    int r = color.red();
    int g = color.green();
    int b = color.blue();

    for (int i = 0; i < featuresCount; ++i)
    {
        GeoFeature* feature = layer->getFeature(i);
        feature->setColor(r, g, b, true);
    }
    emit sigUpdateOpengl();
}

// 2. classify style
void LayerStyleDialog::processCategorizedStyle()
{
    int featuresCount = layer->getFeatureCount();
    int fieldIndex = classifyFieldComboBox->currentIndex();
    //qDebug()<<"featuresCount:"<<featuresCount;
    //qDebug()<<"fieldIndex:"<<fieldIndex;

    if (classifyResultWidget->rowCount() != featuresCount)
        return;
    for (int iRow = 0; iRow < featuresCount; ++iRow){
        GeoFeature *feature =layer->getFeature(iRow);
        switch(feature->getFieldType(fieldIndex))
        {
        default:
            break;
        case kFieldInt:
        {
            QVector<int> interruptValue;
            int rowCount=interruptWidget->rowCount();
            for(int iRow=0;iRow<rowCount;++iRow){
                interruptValue.append(interruptWidget->item(iRow,0)->text().toInt());
            }
            int value;
            feature->getField(fieldIndex, &value);
            for (int i = 0; i < rowCount; i++){
                if(value>=interruptValue[i]&&value<interruptValue[i+1]){
                    const QWidget* widget = classifyResultWidget->cellWidget(i, 0);
                    const auto& children = widget->children();
                    ColorBlockWidget* colorWidget = (ColorBlockWidget*)children.at(2);
                    // color-block's color
                    QColor color = colorWidget->getColor();
                    // update feature's color
                    feature->setColor(color.red(), color.green(), color.blue(), true);
                }
            }
            break;
        }
        case kFieldDouble:
        {
            QVector<double> interruptValue;
            double rowCount=interruptWidget->rowCount();
            for(int iRow=0;iRow<rowCount;++iRow){
                interruptValue.append(interruptWidget->item(iRow,0)->text().toDouble());
            }
            double value;
            feature->getField(fieldIndex, &value);
            for (int i = 0; i < rowCount; ++i){
                if(value>=interruptValue[i]&&value<interruptValue[i+1]){
                    const QWidget* widget = classifyResultWidget->cellWidget(i, 0);
                    const auto& children = widget->children();
                    ColorBlockWidget* colorWidget = (ColorBlockWidget*)children.at(2);
                    // color-block's color
                    QColor color = colorWidget->getColor();
                    // update feature's color
                    feature->setColor(color.red(), color.green(), color.blue(), true);
                }
            }
            break;
        }
        case kFieldText:
        {
            QVector<QString> interruptValue;
            int rowCount=classifyResultWidget->rowCount();
            for(int iRow=0;iRow<rowCount;++iRow){
                interruptValue.append(interruptWidget->item(iRow,1)->text());
            }
            QString value;
            feature->getField(fieldIndex,&value);
            for(int i=0;i<rowCount;++i){
                if(value==interruptValue[i]){
                    const QWidget* widget = classifyResultWidget->cellWidget(i, 0);
                    const auto& children = widget->children();
                    ColorBlockWidget* colorWidget = (ColorBlockWidget*)children.at(2);
                    // color-block's color
                    QColor color = colorWidget->getColor();
                    // update feature's color
                    feature->setColor(color.red(), color.green(), color.blue(), true);
                }
            }
            break;
        }
        }
        /*
        GeoFeature* feature = layer->getFeature(iRow);
        const QWidget* widget = classifyResultWidget->cellWidget(iRow, 0);
        const auto& children = widget->children();
        // 3 children: layout + checkbox + widget(color block)
        //QHBoxLayout* hLayout = (QHBoxLayout*)children.at(0);
        //QCheckBox* checkBox = (QCheckBox*)children.at(1);
        ColorBlockWidget* colorWidget = (ColorBlockWidget*)children.at(2);
        // color-block's color
        QColor color = colorWidget->getColor();
        // update feature's color
        feature->setColor(color.red(), color.green(), color.blue(), true);
        */
    }
    emit sigUpdateOpengl();
}

// 2. classify style
void LayerStyleDialog::processCategorizedStyle2()
{
    //QMap<QString,QColor> colorKindMap;
    QVector<QString> labels;
    QVector<QColor> colors;
    for(int i=0;i<classifyResultWidget->rowCount();++i)
    {
        QString label=classifyResultWidget->item(i,1)->text();
        const QWidget* widget = classifyResultWidget->cellWidget(i, 0);
        const auto& children = widget->children();
        ColorBlockWidget* colorWidget = (ColorBlockWidget*)children.at(2);
        // color-block's color
        QColor color = colorWidget->getColor();

        //colorKindMap.insert(label,color);
        labels.append(label);
        colors.append(color);
    }
    int featuresCount = layer->getFeatureCount();
    int fieldIndex = classifyFieldComboBox->currentIndex();
    qDebug()<<"featuresCount:"<<featuresCount;
    qDebug()<<"fieldIndex:"<<fieldIndex;
    qDebug()<<"classifyResultWidget->rowCount():"<<classifyResultWidget->rowCount();
    //int rowCount=classifyResultWidget->rowCount();
    //if (classifyResultWidget->rowCount() != featuresCount)
        //return;
    switch(layer->getFieldDefn(fieldIndex)->getType()){
    default:
        break;
    case kFieldInt:{
        /*
        QVector<int> interruptValue;
        int rowCount=interruptWidget->rowCount();
        for(int iRow=0;iRow<rowCount;++iRow){
            interruptValue.append(interruptWidget->item(iRow,0)->text().toInt());
        }
        int value;
        feature->getField(fieldIndex, &value);
        for (int i = 0; i < rowCount; i++){
            if(value>=interruptValue[i]&&value<interruptValue[i+1]){
                const QWidget* widget = classifyResultWidget->cellWidget(i, 0);
                const auto& children = widget->children();
                ColorBlockWidget* colorWidget = (ColorBlockWidget*)children.at(2);
                // color-block's color
                QColor color = colorWidget->getColor();
                // update feature's color
                feature->setColor(color.red(), color.green(), color.blue(), true);
            }
        }
        */
        break;
    }
    case kFieldDouble:{
        /*
        QVector<double> interruptValue;
        double rowCount=interruptWidget->rowCount();
        for(int iRow=0;iRow<rowCount;++iRow){
            interruptValue.append(interruptWidget->item(iRow,0)->text().toDouble());
        }
        double value;
        feature->getField(fieldIndex, &value);
        for (int i = 0; i < rowCount; ++i){
            if(value>=interruptValue[i]&&value<interruptValue[i+1]){
                const QWidget* widget = classifyResultWidget->cellWidget(i, 0);
                const auto& children = widget->children();
                ColorBlockWidget* colorWidget = (ColorBlockWidget*)children.at(2);
                // color-block's color
                QColor color = colorWidget->getColor();
                // update feature's color
                feature->setColor(color.red(), color.green(), color.blue(), true);
            }
        }
        */
        break;
    }
    case kFieldText:{
        QVector<QString> interruptValue;
        int rowCount=classifyResultWidget->rowCount();
        qDebug()<<"rowCount="<<rowCount;
        for(int iRow=0;iRow<rowCount;++iRow){
            interruptValue.append(classifyResultWidget->item(iRow,1)->text());
        }
        qDebug()<<"[Start] go through feayures";
        for (int iRow = 0; iRow < featuresCount; ++iRow){
            //qDebug()<<"curRow:"<<iRow;
            GeoFeature *feature =layer->getFeature(iRow);
            QString value;
            feature->getField(fieldIndex,&value);
            for(int i=0;i<rowCount;++i){
                if(value==interruptValue[i]){
                    const QWidget* widget = classifyResultWidget->cellWidget(i, 0);
                    const auto& children = widget->children();
                    ColorBlockWidget* colorWidget = (ColorBlockWidget*)children.at(2);
                    // color-block's color
                    QColor color = colorWidget->getColor();
                    // update feature's color
                    feature->setColor(color.red(), color.green(), color.blue(), true);
                }
            }
        }
        qDebug()<<"finish QString classify";
        break;
    }
    }
    emit sigAddColorTreeBlock(layer,labels,colors);
    emit sigUpdateOpengl();
}

QVector<int> LayerStyleDialog::getMeanInterruptInt(int kindNum,QVector<int> values)
{
    QVector<int> results;
    int valueCount=values.size();
    if(kindNum>valueCount){
        QVector<int>::iterator max=std::max_element(std::begin(values),std::end(values));
        QVector<int>::iterator min=std::min_element(std::begin(values),std::end(values));
        int biggest=*max;
        int smallest=*min;
        results.append(smallest);
        results.append(biggest);
    }
    else{
        QVector<int>::iterator max=std::max_element(std::begin(values),std::end(values));
        QVector<int>::iterator min=std::min_element(std::begin(values),std::end(values));
        int biggest=*max;
        int smallest=*min;
        int stepSize=int((biggest-smallest)/kindNum);
        for(int iKind=0;iKind<kindNum;iKind++){
            int kindValue=smallest+(iKind*stepSize);
            if(kindValue>biggest){
                kindValue=biggest;
            }
            results.append(kindValue);
        }
    }
    return results;
}

QVector<double> LayerStyleDialog::getMeanInterruptDouble(int kindNum,QVector<double> values)
{
    QVector<double> results;
    int valueCount=values.size();
    if(kindNum>valueCount){
        QVector<double>::iterator max=std::max_element(std::begin(values),std::end(values));
        QVector<double>::iterator min=std::min_element(std::begin(values),std::end(values));
        double biggest=*max;
        double smallest=*min;
        results.append(smallest);
        results.append(biggest);
    }
    else{
        QVector<double>::iterator max=std::max_element(std::begin(values),std::end(values));
        QVector<double>::iterator min=std::min_element(std::begin(values),std::end(values));
        double biggest=*max;
        double smallest=*min;
        double stepSize=double((biggest-smallest)/kindNum);
        for(int iKind=0;iKind<kindNum;iKind++){
            double kindValue=smallest+(iKind*stepSize);
            if(kindValue>biggest){
                kindValue=biggest;
            }
            results.append(kindValue);
        }
    }
    return results;
}

void LayerStyleDialog::classifyInt(int fieldIndex, const QColor& startColor, const QColor& endColor)
{
    //int featuresCount = layer->getFeatureCount();
    //int kindNum=spinboxKindNum->value();
    QVector<int> interruptValue;
    int rowCount=interruptWidget->rowCount();
    for(int iRow=0;iRow<rowCount;++iRow)
    {
        interruptValue.append(interruptWidget->item(iRow,0)->text().toInt());
    }
    // R, G, B increment
    double deltaR = (endColor.red() - startColor.red()) / rowCount;
    double deltaG = (endColor.green() - startColor.green()) / rowCount;
    double deltaB = (endColor.blue() - startColor.blue()) / rowCount;

    for(int iRow=0;iRow<interruptValue.size();++iRow)
    {
        QColor color(
            startColor.red() + int(deltaR * iRow),
            startColor.green() + int(deltaG * iRow),
            startColor.blue() + int(deltaB * iRow)
        );
        QString label;
        if(iRow==interruptValue.size()-1){
            label=QString::number(interruptValue[iRow]);
        }
        else{
            label=QString::number(interruptValue[iRow])+"～"+QString::number(interruptValue[iRow+1]);
        }
        insertClassifyItem(classifyResultWidget,iRow,iRow,color,label);
    }
}

void LayerStyleDialog::classifyDouble(int fieldIndex, const QColor& startColor, const QColor& endColor)
{
    //int featuresCount = layer->getFeatureCount();
    QVector<double> interruptValue;
    int rowCount=interruptWidget->rowCount();
    for(int iRow=0;iRow<rowCount;++iRow)
    {
        interruptValue.append(interruptWidget->item(iRow,0)->text().toDouble());
    }
    // R, G, B increment
    double deltaR = (endColor.red() - startColor.red()) / rowCount;
    double deltaG = (endColor.green() - startColor.green()) / rowCount;
    double deltaB = (endColor.blue() - startColor.blue()) / rowCount;

    for(int iRow=0;iRow<interruptValue.size();++iRow)
    {
        QColor color(
            startColor.red() + int(deltaR * iRow),
            startColor.green() + int(deltaG * iRow),
            startColor.blue() + int(deltaB * iRow)
        );
        QString label;
        if(iRow==interruptValue.size()-1){
            label=QString::number(interruptValue[iRow]);
        }
        else{
            label=QString::number(interruptValue[iRow])+"～"+QString::number(interruptValue[iRow+1]);
        }
        insertClassifyItem(classifyResultWidget,iRow,iRow,color,label);
    }
}

void LayerStyleDialog::classifyString(int fieldIndex, const QColor& startColor, const QColor& endColor)
{
    QVector<QString> interruptValue;
    interruptValue=getFieldKinds(fieldIndex);
    int kindNum=interruptValue.size();
    classifyResultWidget->setRowCount(kindNum);
    // R, G, B increment
    double deltaR = (endColor.red() - startColor.red()) / kindNum;
    double deltaG = (endColor.green() - startColor.green()) / kindNum;
    double deltaB = (endColor.blue() - startColor.blue()) / kindNum;
    qDebug()<<"interruptValue.size()-->"<<interruptValue.size();
    for(int iRow=0;iRow<interruptValue.size();++iRow)
    {
        QColor color(
            startColor.red() + int(deltaR * iRow),
            startColor.green() + int(deltaG * iRow),
            startColor.blue() + int(deltaB * iRow)
        );
        QString label=interruptValue[iRow];
        insertClassifyItem(classifyResultWidget,iRow,iRow,color,label);
        qDebug()<<"insert row"<<iRow;
    }
}

void LayerStyleDialog::on_spinboxKindNum_valueChanged(int arg1)
{
    int featuresCount=layer->getFeatureCount();
    int fieldIndex = classifyFieldComboBox->currentIndex();
    switch(layer->getFieldDefn(fieldIndex)->getType())
    {
    default:
        break;
    case kFieldInt:
    {
        QVector<int> interruptValue;
        QVector<int> values;
        for(int iFeature=0;iFeature<featuresCount;++iFeature)
        {
            GeoFeature *feature =layer->getFeature(iFeature);
            int value;
            feature->getField(fieldIndex, &value);
            values.append(value);
        }
        interruptValue=getMeanInterruptInt(arg1,values);
        for(int iRow=0;iRow<interruptValue.size();++iRow)
        {
            interruptWidget->setRowCount(interruptValue.size());
            QTableWidgetItem *item=new QTableWidgetItem();
            item->setText(QString::number(interruptValue[iRow]));
            interruptWidget->setItem(iRow,0,item);
        }
        break;
    }

    }

}


















